﻿using StockTradTest;
using StockTradTest.Data;
using StockTradTest.strategy;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestGraphic
{
    public partial class Form3 : Form
    {
        string record = "";
        Graphics graphics;
        //绘图用缓存
        Bitmap bmp;
        readonly Pen pen;
        readonly Brush brush;

        private async Task RunOnceAsync(string code)
        {
            await foreach (string str in GetStockHistory.UpdateDayAsync(code))
            {
                label_Log.Text = str;
            }
            label_Log.Text = "";
        }
        public Form3()
        {
            pen = new Pen(Color.Black, 1);
            brush = new SolidBrush(Color.Black);
            InitializeComponent();

            bmp = new Bitmap(Width, Height);
            graphics = Graphics.FromImage(bmp);


            //Clear();
            textBox_Code.Text = "601166";
            progressBar.Visible = false;
        }
        private void Clear()
        {
            graphics.Clear(Color.WhiteSmoke);
            graphics.FillRectangle(brush, new RectangleF(2, 2, Width - 20, (int)(Height - 100 - 1)));
            graphics.DrawRectangle(pen, new Rectangle(1, 1, Width - (int)pen.Width - 18, (int)(Height - 100)));
            record = "";
        }

        private void Disable(bool tof)
        {
            if(tof)
            {
                button_Calc.Enabled = false;
                button_Log.Enabled = false;
            }
            else
            {
                button_Calc.Enabled = true;
                button_Log.Enabled = true;
            }
        }
        private async void Button_Calc_ClickAsync(object sender, EventArgs e)
        {
            Disable(true);
            Clear();
            //MessageBox.Show(textBox_Code.Text);
            await RunOnceAsync(textBox_Code.Text);
            label_Log.Text = "更新完成,开始计算策略";
            progressBar.Visible = true;
            progressBar.Value = 0;
            TestTradBase.isRecord = true;
            //测试位置
            Test1();
            //测试结束
            label_Log.Text = "策略执行完成";
            progressBar.Value = 100;
            progressBar.Visible = false;
            Disable(false);
        }

        void Test1()
        {
            string[] temp = textBox_Variable.ToString().Split(',');
            if(!int.TryParse(temp[0], out int startDate) || !int.TryParse(temp[1], out int endDate))
            {
                startDate = 0;
                endDate = int.MaxValue;
            }
            else if(endDate < startDate)
            {
                startDate = 0;
                endDate = int.MaxValue;
            }
            string tempRecord;
            
            List<double> basefunds = MyStrategy.TradBase(textBox_Code.Text,out tempRecord,startDate,endDate);
            if(basefunds == null || basefunds.Count == 0)
            {

                return;
            }

            record += string.Format("基础数据:\n{0}\n", tempRecord);

            bool o = false;
            bool a = false;
            bool b = false;
            bool c = false;
            bool d = false;
            bool e = false;
            bool f = false;
            List<double> funds0 = new List<double>(),
                funds1 = new List<double>(),
                funds2 = new List<double>(),
                funds3 = new List<double>(),
                funds4 = new List<double>(),
                funds5 = new List<double>(),
                funds6 = new List<double>();
            List<int> buyOrsell;

            Thread thread0 = new Thread(() =>
            {
                string tempRecord; MyStrategy myStrategy = new MyStrategy();
                funds0 = myStrategy.TradeMiddleTest(textBox_Code.Text, 5, out buyOrsell,out tempRecord, true, startDate, endDate);
                record += string.Format("策略变量{0}:\n{1}\n", 5, tempRecord);
                o = true;//如果执行则返回true
            });
            Thread thread1 = new Thread(() =>
            {
                string tempRecord; MyStrategy myStrategy = new MyStrategy();
                funds1 = myStrategy.TradeMiddleTest(textBox_Code.Text, 10, out buyOrsell, out tempRecord, true, startDate, endDate);
                record += string.Format("策略变量{0}:\n{1}\n", 10, tempRecord);
                a = true;//如果执行则返回true
            });
            Thread thread2 = new Thread(() =>
            {
                string tempRecord; MyStrategy myStrategy = new MyStrategy();
                funds2 = myStrategy.TradeMiddleTest(textBox_Code.Text, 20, out buyOrsell, out tempRecord, true, startDate, endDate);
                record += string.Format("策略变量{0}:\n{1}\n", 20, tempRecord);
                b = true;//如果执行则返回true
            });
            Thread thread3 = new Thread(() =>
            {
                string tempRecord; MyStrategy myStrategy = new MyStrategy();
                funds3 = myStrategy.TradeMiddleTest(textBox_Code.Text, 30, out buyOrsell, out tempRecord, true, startDate, endDate);
                record += string.Format("策略变量{0}:\n{1}\n", 30, tempRecord);
                b = true;//如果执行则返回true
            });
            Thread thread4 = new Thread(() =>
            {
                string tempRecord; MyStrategy myStrategy = new MyStrategy();
                funds4 = myStrategy.TradeMiddleTest(textBox_Code.Text, 60, out buyOrsell, out tempRecord, true, startDate, endDate);
                record += string.Format("策略变量{0}:\n{1}\n", 60, tempRecord);
                d = true;//如果执行则返回true
            });
            Thread thread5 = new Thread(() =>
            {
                string tempRecord; MyStrategy myStrategy = new MyStrategy();
                funds5 = myStrategy.TradeMiddleTest(textBox_Code.Text, 120, out buyOrsell, out tempRecord, true, startDate, endDate);
                record += string.Format("策略变量{0}:\n{1}\n", 120, tempRecord);
                e = true;//如果执行则返回true
            });
            Thread thread6 = new Thread(() =>
            {
                string tempRecord; MyStrategy myStrategy = new MyStrategy();
                funds6 = myStrategy.TradeMiddleTest(textBox_Code.Text, 250, out buyOrsell, out tempRecord, true, startDate, endDate);
                record += string.Format("策略变量{0}:\n{1}\n", 250, tempRecord);
                f = true;//如果执行则返回true
            });

            thread0.Start();
            thread1.Start();
            thread2.Start();
            thread3.Start();
            thread4.Start();
            thread5.Start();
            thread6.Start();
            //等待线程结束
            thread0.Join();
            thread1.Join();
            thread2.Join();
            thread3.Join();
            thread4.Join();
            thread5.Join();
            thread6.Join();
            progressBar.Value = 90;
            if (o)
            {
                double[] data = new double[] { funds0.Min(), funds0.Max(),
                funds1.Min(), funds1.Max(),
                funds2.Min(), funds2.Max(),
                funds3.Min(), funds3.Max(),
                funds4.Min(), funds4.Max(),
                funds5.Min(), funds5.Max(),
                funds6.Min(), funds6.Max(), basefunds.Min(),basefunds.Max() };
                double minData = data.Min();
                double maxData = data.Max();
                DrawFund(basefunds, minData, maxData, Color.White);
                DrawFund(funds0, minData, maxData, Color.Red);
                DrawFund(funds1, minData, maxData, Color.Orange);
                DrawFund(funds2, minData, maxData, Color.Yellow);
                DrawFund(funds3, minData, maxData, Color.Green);
                DrawFund(funds4, minData, maxData, Color.Blue);
                DrawFund(funds5, minData, maxData, Color.Indigo);
                DrawFund(funds6, minData, maxData, Color.Purple);
            }
            else
            {
                MessageBox.Show("计算失败");
            }















        }
        void Test2()
        {
            string[] temp = textBox_Variable.ToString().Split(',');
            if (!int.TryParse(temp[0], out int startDate) || !int.TryParse(temp[1], out int endDate))
            {
                startDate = 0;
                endDate = int.MaxValue;
            }
            else if (endDate < startDate)
            {
                startDate = 0;
                endDate = int.MaxValue;
            }
            List<double> basefunds = MyStrategy.TradBase(textBox_Code.Text, out string temprecord,startDate, endDate);
            if (basefunds == null || basefunds.Count == 0)
            {

                return;
            }
            record += string.Format("基础数据:\n{0}\n", temprecord);
            progressBar.Value = 10;
            List<double> funds0 = MyStrategy.TradeMaTest(textBox_Code.Text, 5);
            record += string.Format("策略变量{0}:\n{1}\n", 5, temprecord);
            progressBar.Value = 20;
            List<double> funds1 = MyStrategy.TradeMaTest(textBox_Code.Text, 10);
            record += string.Format("策略变量{0}:\n{1}\n", 10, temprecord);
            progressBar.Value = 30;
            List<double> funds2 = MyStrategy.TradeMaTest(textBox_Code.Text, 20);
            record += string.Format("策略变量{0}:\n{1}\n", 20, temprecord);
            progressBar.Value = 40;
            List<double> funds3 = MyStrategy.TradeMaTest(textBox_Code.Text, 30);
            record += string.Format("策略变量{0}:\n{1}\n", 30, temprecord);
            progressBar.Value = 50;
            List<double> funds4 = MyStrategy.TradeMaTest(textBox_Code.Text, 60);
            record += string.Format("策略变量{0}:\n{1}\n", 60, temprecord);
            progressBar.Value = 60;
            List<double> funds5 = MyStrategy.TradeMaTest(textBox_Code.Text, 120);
            record += string.Format("策略变量{0}:\n{1}\n", 120, temprecord);
            progressBar.Value = 70;
            List<double> funds6 = MyStrategy.TradeMaTest(textBox_Code.Text, 250);
            record += string.Format("策略变量{0}:\n{1}\n", 250, temprecord);
            progressBar.Value = 80;

            double[] data = new double[] { funds0.Min(), funds0.Max(),
                funds1.Min(), funds1.Max(),
                funds2.Min(), funds2.Max(),
                funds3.Min(), funds3.Max(),
                funds4.Min(), funds4.Max(),
                funds5.Min(), funds5.Max(),
                funds6.Min(), funds6.Max(), basefunds.Min(),basefunds.Max() };
            double minData = data.Min();
            double maxData = data.Max();
            progressBar.Value = 90;
            DrawFund(basefunds, minData, maxData, Color.White);
            DrawFund(funds0, minData, maxData, Color.Red);
            DrawFund(funds1, minData, maxData, Color.Orange);
            DrawFund(funds2, minData, maxData, Color.Yellow);
            DrawFund(funds3, minData, maxData, Color.Green);
            DrawFund(funds4, minData, maxData, Color.Blue);
            DrawFund(funds5, minData, maxData, Color.Indigo);
            DrawFund(funds6, minData, maxData, Color.Purple);
        }

        /// <summary>
        /// 在图上绘制资金线
        /// </summary>
        /// <param name="code">股票代码</param>
        /// <param name="n">ma天数</param>
        /// <param name="startCount">开始数据</param>
        private void DrawFund(List<double> data, double minData, double maxData, Color color)
        {
            double heightLength = Height - 100 - 10;
            double widthLength = Width - 20;
            double step = widthLength / data.Count;


            List<Point> points = new List<Point>();
            double length = maxData - minData;
            for (int i = 0; i < data.Count; i++)
            {
                points.Add(new Point((int)(i * step + 4), 5 + (int)(heightLength - (data[i] - minData) / length * heightLength)));
            }
            if (points.Count > 0) graphics.DrawLines(new Pen(color, 1), points.ToArray());


        }

        private void Form3_Paint(object sender, PaintEventArgs e)
        {
            this.CreateGraphics().DrawImage(bmp, 0, 0);
        }



        private void Form3_Resize(object sender, EventArgs e)
        {
            //float newx = (this.Width) / x;
            //float newy = (this.Height) / y;
            //SetControls(newx, newy, this);
            bmp = new Bitmap(Width, Height);
            graphics = Graphics.FromImage(bmp);
            Clear();
        }

        private void Button_Log_Click(object sender, EventArgs e)
        {
            TextRecord.Record(record, true);
            TextRecord.OpenRecord();
        }

        private void Form3_FormClosed(object sender, FormClosedEventArgs e)
        {
            Form1.inFocus = true;
        }
    }
}
